home *** CD-ROM | disk | FTP | other *** search
/ Deutsche Edition 1 / Deutsche Edition 1.iso / amok / amok_lha / amok59.lha / AmokEd_V1.02b / txt / EdDisplay.mod < prev    next >
Text File  |  1993-08-15  |  11KB  |  383 lines

  1. (*************************************************************************
  2.  
  3. :Program.    EdDisplay.mod
  4. :Contents.   Screen- and Gadget-Routines for AmokEd
  5. :Author.     Hartmut Goebel
  6. :Language.   Oberon
  7. :Translator. Amiga Oberon V1.17.1
  8. :Imports.    SupLib (Hartmut Goebel)
  9. :History.    V0.1 03 Dec 1990, Hartmut Goebel [hG]
  10. :History.    V1.0 02 Apr 1991 [hG]
  11. :Date.       17 Oct 1991 20:49:23
  12.  
  13. *************************************************************************)
  14. (*
  15. Dieses Modul enthält alle Prozeduren, die für die Steuerung der Bildschirm-
  16. Ein-/Ausgabe nötig sind, sowie die zugehörigen Kommandos.
  17. *)
  18.  
  19. MODULE EdDisplay;
  20.  
  21. IMPORT
  22.   e  : Exec,
  23.   edE: EdErrors,
  24.   edG: EdGlobalVars,
  25.   edL: EdLowLevel,
  26.   g  : Graphics,
  27.   I  : Intuition,
  28.   lst: EdLists,
  29.   ol : OberonLib,
  30.   sl : SupLib,
  31.   str: Strings,
  32.   sys: SYSTEM;
  33.  
  34. CONST
  35.   NoPropFonts = "No Proportional Fonts!!";
  36.   UnableToFindFont = "Unable to find font";
  37.  
  38. PROCEDURE ColT* (n{0}: INTEGER): INTEGER;
  39.   BEGIN RETURN (edG.XTBase + n * edG.XSize); END ColT;
  40. PROCEDURE RowT* (n{0}: INTEGER): INTEGER;
  41.   BEGIN RETURN (edG.YTBase + n * edG.YSize); END RowT;
  42. PROCEDURE Col* (n{0}: INTEGER): INTEGER;
  43.   BEGIN RETURN (edG.XBase + n * edG.XSize); END Col;
  44. PROCEDURE Row* (n{0}: INTEGER): INTEGER;
  45.   BEGIN RETURN (edG.YBase + n * edG.YSize); END Row;
  46.  
  47.  
  48. PROCEDURE SetPen*(Line: LONGINT);
  49. VAR
  50.   Pen : SHORTINT;
  51. BEGIN
  52.   Pen := 1;
  53.   IF (Line>=edG.Block.SNum) AND (Line<=edG.Block.ENum)
  54.   AND ~(edG.commLineMode IN edG.Status) THEN
  55.     Pen := 2;
  56.   END;
  57.   IF (edG.Config.screenDepth = 1)
  58.   OR ((edG.WBScreenDepth = 1) AND (edG.Screen = NIL)) THEN
  59.     g.SetAPen(edG.RPort,1);
  60.     IF Pen = 1 THEN
  61.       g.SetDrMd(edG.RPort,g.jam2);
  62.     ELSE
  63.       g.SetDrMd(edG.RPort,SHORTSET{g.inversvid}+g.jam2);
  64.     END;
  65.   ELSIF Pen # edG.RPort.fgPen THEN
  66.     g.SetAPen(edG.RPort,Pen);
  67.   END;
  68. END SetPen;
  69.  
  70.  
  71. PROCEDURE TextCursor*(on:BOOLEAN);
  72. VAR
  73.   buf : edG.StringPtr;
  74.   px, py: INTEGER;
  75.   Block: BOOLEAN;
  76. BEGIN
  77.   IF NOT (edG.noCursor IN edG.Status) THEN
  78.     edL.MoveToCursor;
  79.     Block := (edG.Text=edG.Block.Owner) AND (edG.Text.line>=edG.Block.SNum)
  80.              AND (edG.Text.line<=edG.Block.ENum);
  81.     g.SetAPen(edG.RPort,1);
  82.     IF on THEN
  83.       g.SetDrMd(edG.RPort,SHORTSET{g.complement});
  84.       px := Col(edG.Text.pos-edG.Text.topPos);
  85.       py := Row(SHORT(edG.Text.line-edG.Text.topLine));
  86.       g.RectFill(edG.RPort,px,py,px+edG.XSize-1,py+edG.YSize-1);
  87.     ELSE
  88.       g.SetDrMd(edG.RPort,g.jam2);
  89.       IF Block AND (edG.Text.pos<=edG.LineBufferLen)
  90.       AND (edG.Config.screenDepth = 1) THEN
  91.         g.SetDrMd(edG.RPort,SHORTSET{g.inversvid}+g.jam2);
  92.       END;
  93.       IF Block AND (edG.Config.screenDepth # 1)
  94.       AND NOT(edG.commLineMode IN edG.Status) THEN
  95.         g.SetAPen(edG.RPort,2); END;
  96.       buf := sys.ADR(edG.LineBuffer[edG.Text.pos]);
  97.       IF buf[0] # 0X THEN
  98.         g.Text(edG.RPort,buf^,1);
  99.       ELSE
  100.         g.Text(edG.RPort,edG.Spaces,1);
  101.       END;
  102.     END;
  103.     g.SetDrMd(edG.RPort,g.jam2);
  104.   END;
  105. END TextCursor;
  106.  
  107. (*----------------------------------------------------------------------*)
  108.  
  109. PROCEDURE SetWindowParams*;
  110. VAR
  111.  win: I.WindowPtr;
  112. BEGIN
  113.   win := edG.Text.window;
  114.   edG.RPort := win.rPort;
  115.   edG.XSize := edG.RPort.font.xSize;
  116.   edG.YSize := edG.RPort.font.ySize;
  117.   edG.XBase := win.borderLeft;
  118.   edG.YBase := win.borderTop;
  119.   edG.XPixs := win.width-win.borderRight-edG.XBase;
  120.   edG.YPixs := win.height-win.borderBottom-edG.YBase;
  121.   edG.Columns := edG.XPixs DIV edG.XSize;
  122.   edG.Rows := edG.YPixs DIV edG.YSize;
  123.   edG.XTBase := edG.XBase;
  124.   edG.YTBase := edG.YBase+edG.RPort.font.baseline;
  125.   IF NOT (edG.iconMode IN edG.Text.status) THEN edG.SetPropKnob; END;
  126. END SetWindowParams;
  127.  
  128. (*----------------------------------------------------------------------*)
  129.  
  130. (* bringt ab <start> <n> Zeilen auf den Bildschirm, hiezu müssen         *)
  131. (* edG.Text.topLinePtr und edG.Text.actLinePtr den aktuellen Wert haben  *)
  132.  
  133. PROCEDURE TextDisplaySeg*(start, n: INTEGER);
  134. VAR
  135.   i,c: INTEGER;
  136.   ptr: edG.StringPtr;
  137.   thisLine: edG.LinePtr;
  138. BEGIN
  139.   IF edG.NoScreenUpdate > 0 THEN RETURN; END;
  140.   thisLine := edG.Text.topLinePtr;
  141.   IF NOT (edG.commLineMode IN edG.Status) THEN
  142.     lst.GoForwardNil(thisLine,start); END;
  143.   i := start;
  144.   WHILE (i < start+n) AND (i < edG.Rows) AND (thisLine#NIL) DO
  145.     IF edG.commLineMode IN edG.Status THEN
  146.       ptr := sys.ADR(edG.LineBuffer);
  147.       g.SetAPen(edG.RPort,1);
  148.     ELSIF (thisLine = edG.Text.actLinePtr) THEN
  149.       ptr := sys.ADR(edG.LineBuffer);
  150.       SetPen(edG.Text.line);
  151.     ELSE
  152.       ptr := thisLine(edG.Line).string;
  153.       SetPen(edG.Text.topLine+i);
  154.     END; (* IF *)
  155.     c := str.Length(ptr^)-edG.Text.topPos;
  156.     IF c > 0 THEN
  157.       INC(ptr,edG.Text.topPos);
  158.       g.Move(edG.RPort,ColT(0),RowT(i));
  159.       IF c > edG.Columns THEN c := edG.Columns; END;
  160.       g.Text(edG.RPort,ptr^,c);
  161.     END;
  162.     INC(i);
  163.     thisLine := thisLine.next(edG.Line);
  164.   END (* WHILE *)
  165. END TextDisplaySeg;
  166.  
  167.  
  168. PROCEDURE TextRedisplay*;
  169. BEGIN
  170.   IF edG.NoScreenUpdate > 0 THEN
  171.     RETURN; END;
  172.   g.SetAPen(edG.RPort,0);
  173.   IF edG.commLineMode IN edG.Status THEN
  174.     g.RectFill(edG.RPort,Col(0),Row(edG.Rows-1),
  175.                edG.XBase+edG.XPixs,edG.YBase+edG.YPixs);
  176.   ELSE
  177.     g.RectFill(edG.RPort, edG.XBase, edG.YBase,
  178.                edG.XBase+edG.XPixs, edG.YBase+edG.YPixs);
  179.   END;
  180.   TextDisplaySeg(0,edG.Rows);
  181.   (*edG.SetProp; (* eben nicht SetPropKnob!*) *)
  182. END TextRedisplay;
  183.  
  184.  
  185. PROCEDURE TextRedisplayCurrentLine*;
  186. VAR
  187.   row: INTEGER;
  188. BEGIN
  189.   IF edG.NoScreenUpdate > 0 THEN
  190.     RETURN; END;
  191.   row := SHORT(edG.Text.line-edG.Text.topLine);
  192.   g.SetAPen(edG.RPort,0);
  193.   g.RectFill(edG.RPort, Col(0), Row(row),
  194.              edG.XBase+edG.XPixs, Row(row+1)-1);
  195.   TextDisplaySeg(row,1);
  196. END TextRedisplayCurrentLine;
  197.  
  198. (*------------------------------------------------------------------------
  199. * Syncronisiert den Bildschirm mit dem Text bezüglich der aktuellen
  200. * Werte edG.Text.line, edG.Text.pos und edG.Text.actLinePtr
  201. * Anwendung: line, pos und actLinePtr setzten, TextSync aufrufen
  202. *)
  203.  
  204. PROCEDURE TextSync*;
  205. VAR
  206.   redraw : BOOLEAN;
  207. BEGIN
  208.   redraw := FALSE;
  209.   IF NOT (edG.NoScreenUpdate > 0) THEN
  210.     IF (edG.Text.pos - edG.Text.topPos >= edG.Columns)
  211.     OR (edG.Text.pos < edG.Text.topPos) THEN
  212.       redraw := TRUE;
  213.       edG.Text.topPos := edG.Text.pos - edG.Columns DIV 2;
  214.       IF edG.Text.topPos < 0 THEN edG.Text.topPos := 0; END;
  215.     END;
  216.     IF (edG.Text.line - edG.Text.topLine >= edG.Rows)
  217.     OR (edG.Text.line < edG.Text.topLine) THEN
  218.       redraw := TRUE;
  219.       edG.Text.topLine := edG.Text.line - edG.Rows DIV 2;
  220.       IF edG.Text.topLine < 0 THEN edG.Text.topLine := 0; END;
  221.       edG.Text.topLinePtr := edG.Text.actLinePtr;
  222.       lst.GoBackwardNil(edG.Text.topLinePtr,edG.Text.line-edG.Text.topLine);
  223.     END;
  224.   END; (* NOT NoScreenUpdate *)
  225.   edL.FillUpSpaces;
  226.   IF redraw THEN
  227.     INCL(edG.Status,edG.alreadyRedrawn);
  228.     TextRedisplay;
  229.   ELSE
  230.     EXCL(edG.Status,edG.alreadyRedrawn);
  231.   END;
  232. END TextSync;
  233.  
  234. (*------------------------------------------------------------------------
  235. *
  236. * Kopiert den ZeilenPuffer nach Entfernen der Spaces
  237. * am Zeilenende in die Aktuelle Zeile
  238. *)
  239.  
  240. PROCEDURE PutBackLine*;
  241. VAR
  242.   thisLine: edG.LinePtr;
  243.   ptr: edG.StringPtr;
  244.   len, neededSpace : INTEGER;
  245. BEGIN
  246.   edL.StripEndSpaces;
  247.   len := edG.LineBufferLen;
  248.   IF NOT (edG.commLineMode IN edG.Status) THEN
  249.     thisLine := edG.Text.actLinePtr;
  250.     WITH thisLine:edG.Line DO
  251.       IF (thisLine.string^ # edG.LineBuffer) THEN
  252.         INCL(edG.Text.status,edG.modified);
  253.         EXCL(edG.Text.status,edG.quit); (* explizit: sicher ist sicher! *)
  254.         neededSpace := len+edG.ChunkSize-(len MOD edG.ChunkSize);
  255.         IF neededSpace # thisLine.len THEN (* anderer Platzbedarf? *)
  256.           ptr := e.AllocMem(neededSpace,LONGSET{});
  257.           IF ptr # NIL THEN
  258.             e.FreeMem(thisLine.string,thisLine.len);
  259.             thisLine.string := ptr;
  260.             thisLine.len := neededSpace;
  261.           ELSE
  262.             INCL(edG.Status,edG.memoryFail);
  263.             edG.LineBufferLen := thisLine.len;
  264.             e.CopyMemQuick(edG.LineBuffer,thisLine.string^,edG.LineBufferLen);
  265.             thisLine.string[edG.LineBufferLen] := 0X;
  266.             RETURN;
  267.           END; (* IF ptr # NIL *)
  268.         END; (* IF neededSpace # thisLine.len *)
  269.         e.CopyMemQuick(edG.LineBuffer,thisLine.string^,neededSpace);
  270.       END; (* IF thisLine.string^ # edG.LineBuffer *)
  271.     END; (* WITH *)
  272.   END; (* NOT commLineMode *)
  273. END PutBackLine;
  274.  
  275.  
  276. (* Holt aktuelle Zeile in den ZeilenPuffer *)
  277.  
  278. PROCEDURE TextLoad*;
  279. BEGIN
  280.   IF edG.commLineMode IN edG.Status THEN RETURN; END;
  281.   e.CopyMemQuick(edG.Text.actLinePtr(edG.Line).string^,edG.LineBuffer,
  282.                  edG.Text.actLinePtr(edG.Line).len);
  283.   edG.LineBufferLen := str.Length(edG.LineBuffer);
  284.   edL.FillUpSpaces;
  285. END TextLoad;
  286.  
  287. (*----------------------------------------------------------------------*)
  288.  
  289. PROCEDURE TextPosition*(col, row: INTEGER);
  290. BEGIN
  291.   PutBackLine;
  292.   IF col = 0 THEN col  := -1; END;
  293.   edG.Text.pos := edG.Text.topPos+col;
  294.   IF edG.Text.pos > edG.MaxLineLength-2 THEN edG.Text.pos := edG.MaxLineLength-2;
  295.   ELSIF edG.Text.pos < 0 THEN edG.Text.pos := 0 END;
  296.   edG.Text.line := edG.Text.topLine+row;
  297.   edG.Text.actLinePtr := edG.Text.topLinePtr;
  298.   IF row > 0 THEN
  299.     IF edG.Text.line >= edG.Text.numberOfLines THEN
  300.       edG.Text.line := edG.Text.numberOfLines-1; END;
  301.     lst.GoForwardNil(edG.Text.actLinePtr,edG.Text.line-edG.Text.topLine);
  302.   ELSIF row < 0 THEN
  303.     lst.GoBackwardNil(edG.Text.actLinePtr,-row);
  304.     IF edG.Text.line <= 0 THEN
  305.       edG.Text.actLinePtr := edG.Text.lineList.head;
  306.       edG.Text.line := 0;
  307.     END;
  308.   END;
  309.   TextLoad;
  310.   TextSync;
  311. END TextPosition;
  312.  
  313. (*----------------------------------------------------------------------*)
  314.  
  315. (* Schaltet Editior auf <txt> um *)
  316.  
  317. PROCEDURE SwitchEdit*(txt: edG.TextHeaderPtr);
  318. BEGIN
  319.   PutBackLine;
  320.   IF NOT (edG.iconMode IN edG.Text.status) THEN edL.WindowTitle; END;
  321.   edG.Text := txt;
  322.   SetWindowParams;
  323.   TextLoad;
  324.   IF NOT (edG.iconMode IN edG.Text.status) THEN TextSync; END;
  325.   (*edL.WindowTitle;*)
  326. END SwitchEdit;
  327.  
  328. (*----------------------------------------------------------------------*)
  329.  
  330. (* patch to speed up scrolling *)
  331. PROCEDURE FastScrollRaster*(dx,dy,l,t,w,h: INTEGER);
  332. VAR
  333.   depth: POINTER TO BYTE;
  334.   old: BYTE;
  335. BEGIN
  336.    depth := sys.ADR(edG.RPort.bitMap.depth);
  337.    old := depth^;
  338.  
  339.    e.Forbid();
  340.    IF (edG.Block.SNum > edG.Text.topLine + edG.Rows)
  341.    OR (edG.Block.ENum < edG.Text.topLine - 1) THEN
  342.       depth^ := 1;
  343.    END;
  344.    g.ScrollRaster(edG.RPort,dx,dy,l,t,w,h);
  345.    depth^ := old;
  346.    e.Permit();
  347. END FastScrollRaster;
  348.  
  349. (*----------------------------------------------------------------------*)
  350.  
  351. PROCEDURE doSetFont*;
  352. VAR
  353.   font: g.TextFontPtr;
  354.   size: LONGINT;
  355. BEGIN
  356.   IF NOT edL.StrToInt(edG.Arg[1],size) OR (size > MAX(INTEGER)) THEN
  357.     edL.Title(edG.BadArgument); edG.Rc := edE.cmdError;
  358.     RETURN;
  359.   END;
  360.   font := sl.GetFont(edG.Arg[0]^,SHORT(size));
  361.   IF font # NIL THEN
  362.     IF g.proportional IN font.flags THEN
  363.       g.CloseFont(font);
  364.       edL.Title(NoPropFonts); edG.Rc := edE.cmdFailed;
  365.       RETURN;
  366.     END;
  367.     IF edG.Text.font # NIL THEN
  368.       g.CloseFont(edG.Text.font); END;
  369.     edG.Text.font := font;
  370.     g.SetFont(edG.Text.window.rPort,font);
  371.     g.SetRast(edG.Text.window.rPort,0);
  372.     I.RefreshWindowFrame(edG.Text.window);
  373.     SetWindowParams;
  374.     TextSync;
  375.     IF NOT (edG.alreadyRedrawn IN edG.Status) THEN TextRedisplay; END;
  376.   ELSE
  377.     edL.Title(UnableToFindFont); edG.Rc := edE.cmdFailed;
  378.   END;
  379. END doSetFont;
  380.  
  381. END EdDisplay.
  382.  
  383.